<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="test"></div>
    <div id="test1"></div>
    <script src="../lib/17//react.development.js"></script>
    <script src="../lib/17/react-dom.development.js"></script>
    <script src="../lib/17/babel.min.js"></script>
    <script src="../lib/17/prop-types.js"></script>
    <script type="text/babel">
        // 新的 生命周期钩子
        //      componentWillMount、componentWillReceiveProps、componentWillUpdate 即将被废弃，18 版本需要加上 UNSAFE_ 前缀才能使用
        //      Will 相关的，除了 componentWillUnmount 都要加 UNSAFE_
        //      原因：未来设计新的异步渲染，容易被造成误解

        //      新增  getDerivedStateFromProps 和  getSnapshotBeforeUpdate

        //      初始化阶段：1.constructor；2.getDerivedStateFromProps ；3.render；4.componentDidMount；
        //      更新（setState）阶段：1.getDerivedStateFromProps；2.shouldComponentUpdate；3.render；4.getSnapshotBeforeUpdate；5.componentDidUpdate；
        class LifeCycle extends React.Component {
            constructor(props){
                super(props)
                this.state = { count: 1 }
                console.log('count constructor')
            }
            // 从 props 获取派生的状态（可以把 props 挂载到 state 中）
            static getDerivedStateFromProps(props,state){
                console.log('count getDerivedStateFromProps')
                // console.log(props,state)
                // state 中的 count 使用 setState 不能再更新
                // 状态 全部取决于 props
                return {count:1000 , ...props}
            }
            // UNSAFE_componentWillMount(){
            //     console.log('count UNSAFE_componentWillMount')
            // }
            render() {
                console.log('count render')
                return (
                    <div>
                        <h1>{this.state.count}</h1>
                        <button onClick={this.add}>Add</button>
                        <button onClick={this.add}>unmount</button>
                        <button onClick={this.force}>forceUpdate</button>
                    </div>
                )
            }
            // render 和 update 之间，更新之前获取快照
            // 传递数据给 componentDidUpdate
            getSnapshotBeforeUpdate(){
                console.log('count getSnapshotBeforeUpdate')
                return {aa:1234}
            }
            componentDidMount() {
                console.log('count componentDidMount')
            }
            add = () => {
                let {count} = this.state
                this.setState({count:++count})
            }
            // 必须有返回值（true：更新，false： 不更新）
            shouldComponentUpdate(){
                console.log('count shouldComponentUpdate')
                return true
            }
            // UNSAFE_componentWillUpdate(){
            //     console.log('count UNSAFE_componentWillUpdate') 
            // }
            componentDidUpdate(a,b,snapval){
                console.log('count componentDidUpdate',a,b,snapval)
            }
            force = ()=>{
                this.forceUpdate()
            }
            componentWillUnmount() {
                console.log('count componentWillUnmount')
            }
           
        }
        
        class Child extends React.Component{
            UNSAFE_componentWillReceiveProps(){
                 console.log('Child UNSAFE_componentWillReceiveProps')
            }
            shouldComponentUpdate(){
                 console.log('Child shouldComponentUpdate')
                 return true
            }
            UNSAFE_componentWillUpdate(){
                 console.log('Child UNSAFE_componentWillUpdate')
            }
            componentDidUpdate(){
                 console.log('Child componentDidUpdate')
            }
            render(){
                console.log('Child render')
                return <div>
                        <p>child</p>
                    </div>
            }
        }
        class Parent extends React.Component{
            state = {status:false}
            changeStatus = ()=>{
                const {status} = this.state
                this.setState({status:!status})
            }
            render(){
                return <div>
                    <p>parent</p>
                    <Child status={this.state.status}/>
                    <button onClick={this.changeStatus}>changeStatus</button>
                </div>
            }
        }
        ReactDOM.render(<LifeCycle vvv = {100}/>, document.getElementById('test'))
        ReactDOM.render(<Parent />, document.getElementById('test1'))
    </script>
</body>

</html>